package com.ruoyi.system.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONArray;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.vo.SysMedicinesVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysMedicinesMapper;
import com.ruoyi.system.domain.SysMedicines;
import com.ruoyi.system.service.ISysMedicinesService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 药品Service业务层处理
 * 
 * @author jiashu
 * @date 2025-03-13
 */
@Service
public class SysMedicinesServiceImpl implements ISysMedicinesService 
{

    @Value("${go-fastdfs.upload-url}")
    private String go_fastDFS_upload_url;

    @Value("${go-fastdfs.query-url}")
    private String go_fastDFS_query_url;


    @Value("${ruoyi.profile}")
    private String profile;

    @Value("${go-fastdfs.delete-url}")
    private String go_fastDFS_delete_url;

    @Autowired
    private SysMedicinesMapper sysMedicinesMapper;


    /**
     * 查询药品
     * 
     * @param medicineId 药品主键
     * @return 药品
     */
    @Override
    public SysMedicines selectSysMedicinesByMedicineId(Long medicineId)
    {
        return sysMedicinesMapper.selectSysMedicinesByMedicineId(medicineId);
    }

    /**
     * 查询药品列表
     * 
     * @param sysMedicines 药品
     * @return 药品
     */
    @Override
    public List<SysMedicines> selectSysMedicinesList(SysMedicines sysMedicines)
    {
        return sysMedicinesMapper.selectSysMedicinesList(sysMedicines);
    }

    /**
     * 新增药品
     * 
     * @param sysMedicines 药品
     * @return 结果
     */
    @Override
    public int insertSysMedicines(SysMedicinesVo sysMedicinesVo) throws IOException {
        SysMedicines sysMedicines = new SysMedicines();

        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        sysMedicines.setCreateBy(user.getUserName());
        sysMedicines.setCreateTime(DateUtils.getNowDate());
        BeanUtils.copyBeanProp(sysMedicines , sysMedicinesVo);
        Long deptId = loginUser.getDeptId();

        return sysMedicinesMapper.insertSysMedicines(sysMedicines);
    }


    /**
     * 上传文件
     * @param medicines
     * @param file
     */
//    @Override
//    @Transactional
//    public void importImg(SysMedicines medicines, MultipartFile file) {
//        try {
//            String imageMd5 = medicines.getImageMd5();
//            if (StringUtils.isNotBlank(imageMd5)) {
//                // 删除旧文件
//                HttpUtil.get(go_fastDFS_delete_url + imageMd5);
//            }
//
//            LoginUser loginUser = SecurityUtils.getLoginUser();
//            Long deptId = loginUser.getDeptId();
//            String path = deptId + "/" + medicines.getClassificationId(); // 确保路径合法
//            String filename = file.getOriginalFilename();
////            profile 变量的值为D:/ruoyi/uploadPath
//
//            // 请将文件先下载到临时文件夹
//            // 然后结合下面的demo 修改
//            // 最后删掉临时文件的代码先注释方便我看结果
//            /*
//            public static void main(String[] args) {
//    //文件地址
//    File file = new File("D:\\git\\2.jpg");
//    //声明参数集合
//    HashMap<String, Object> paramMap = new HashMap<>();
//    //文件
//    paramMap.put("file", file);
//    //输出
//    paramMap.put("output","json");
//    //自定义路径
//    paramMap.put("path","image");
//    //场景
//    paramMap.put("scene","image");
//    //上传
//    String result= HttpUtil.post("http://xxxxx:xxxx/group1/upload", paramMap);
//    //输出json结果
//    System.out.println(result);
//}
//             */
//            Map<String, Object> paramMap = new HashMap<>();
//            paramMap.put("file", new InputStreamResource(file.getInputStream(), filename));
//            paramMap.put("filename", filename);  // 显式指定文件名
//            paramMap.put("path", path);
//            paramMap.put("output", "json");
//
//            // 使用 HttpUtil.post 直接上传
//            String post = HttpUtil.post(go_fastDFS_upload_url, paramMap);
//            System.out.println("Go-FastDFS 响应：" + post);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }



    @Transactional
    public void importImg(SysMedicines medicines, MultipartFile file) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long deptId = loginUser.getDeptId();
        File tempFile = null;
        try {
            // 1. 删除旧文件（如果存在）
            String imageMd5 = medicines.getImageMd5();
            if (StringUtils.isNotBlank(imageMd5)) {
                HttpUtil.get(go_fastDFS_delete_url + imageMd5);
            }

            // 2. 创建临时文件
            String tempDir = profile+"/";  // 临时目录（需确保存在）
            String originalFilename = file.getOriginalFilename();
            tempFile = new File(tempDir + UUID.randomUUID() + "_" + originalFilename);

            // 将 MultipartFile 转存到临时文件
            file.transferTo(tempFile);
            System.out.println("临时文件路径: " + tempFile.getAbsolutePath());

            // 3. 准备上传参数
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("file", tempFile);  // 关键改动：直接传递 File 对象
            paramMap.put("path", deptId + "/" + medicines.getClassificationId());
            paramMap.put("output", "json");
            paramMap.put("scene", "medicine");  // 按需添加场景参数

            // 4. 调用 Go-FastDFS 上传
            String response = HttpUtil.post(go_fastDFS_upload_url, paramMap);
            System.out.println("上传响应: " + response);

            // 5. 解析响应（示例）
//            JSONObject json = JSONUtil.parseObj(response);
//            if (!"success".equals(json.getStr("status"))) {
//                throw new RuntimeException("文件上传失败: " + json.getStr("message"));
//            }

            // 6. 更新 medicines 的 MD5 等信息（根据实际响应字段调整）
            String[] param = parseFastDFSResponse(response);
            SysMedicines sysMedicines = new SysMedicines();
            sysMedicines.setStatus("0");
            sysMedicines.setMedicineId(medicines.getMedicineId());
            sysMedicines.setImageMd5(param[0]);
            sysMedicines.setImageDownloadUrl(param[1]);
            sysMedicines.setImagePreviewUrl(param[2]);

            sysMedicinesMapper.updateSysMedicines(sysMedicines);
        } catch (IOException | RuntimeException e) {
            // 异常时触发事务回滚（@Transactional 生效）
            e.printStackTrace();
            throw new RuntimeException("文件处理失败: " + e.getMessage());
        } finally {
            // 7. 清理临时文件
            if (tempFile != null && tempFile.exists()) {
                boolean deleted = tempFile.delete();
                System.out.println("临时文件删除结果: " + deleted);
            }
        }
    }





    /**
     * 修改药品
     * 
     * @param sysMedicines 药品
     * @return 结果
     */
    @Override
    public int updateSysMedicines(SysMedicines sysMedicines)
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        SysUser user = loginUser.getUser();
        sysMedicines.setUpdateBy(user.getUserName());
        sysMedicines.setUpdateTime(DateUtils.getNowDate());

        return sysMedicinesMapper.updateSysMedicines(sysMedicines);
    }

    /**
     *
     * @param sysMedicinesVo
     * @return
     */
    @Override
    public int updateSysMedicines(SysMedicinesVo sysMedicinesVo) throws IOException {
        SysMedicines sysMedicines = new SysMedicines();
        BeanUtils.copyBeanProp(sysMedicines, sysMedicinesVo);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        sysMedicines.setUpdateBy(loginUser.getUsername());
        sysMedicines.setUpdateTime(DateUtils.getNowDate());
        Long deptId = loginUser.getDeptId();
        return sysMedicinesMapper.updateSysMedicines(sysMedicines);
    }

    /**
     * 检查修改的名称是否重名  true 是可以使用这个名称否则是不可以
     * @param sysMedicinesVo
     * @return
     */
    @Override
    public boolean checkUpdateMedicinesName(SysMedicinesVo sysMedicinesVo) {
        boolean result = false;
        SysMedicines sysMedicines = new SysMedicines();
        sysMedicines.setMedicineName(sysMedicinesVo.getMedicineName());
        List<SysMedicines> medicines = selectSysMedicinesList(sysMedicines);
        // 如果修改的名称在数据库中没有则可以使用
        if(medicines.isEmpty()){
            result = true;
        }else if(medicines.size()==1 && medicines.get(0).getMedicineId() == sysMedicinesVo.getMedicineId()){
            // 如果当前名称只查询到1条数据 且就是当前被修改的  可以用使用
            result = true;
        }
        return result;
    }

    /**
     * 批量删除药品
     * 
     * @param medicineIds 需要删除的药品主键
     * @return 结果
     */
    @Override
    public int deleteSysMedicinesByMedicineIds(Long[] medicineIds)
    {
        for (Long medicineId : medicineIds) {
            SysMedicines sysMedicines = sysMedicinesMapper.selectSysMedicinesByMedicineId(medicineId);
            String imageMd5 = sysMedicines.getImageMd5();
            HttpUtil.get(go_fastDFS_delete_url+imageMd5);
        }
        return sysMedicinesMapper.deleteSysMedicinesByMedicineIds(medicineIds);
    }

    /**
     * 删除药品信息
     * 
     * @param medicineId 药品主键
     * @return 结果
     */
    @Override
    public int deleteSysMedicinesByMedicineId(Long medicineId)
    {
        SysMedicines sysMedicines = sysMedicinesMapper.selectSysMedicinesByMedicineId(medicineId);
        String imageMd5 = sysMedicines.getImageMd5();
        HttpUtil.get(go_fastDFS_delete_url+imageMd5);
        return sysMedicinesMapper.deleteSysMedicinesByMedicineId(medicineId);
    }






    /**
     * 解析 go-fastdfs 上传响应，提取 MD5 和 URL 的主路径部分
     * @param responseBody 上传接口返回的 JSON 响应体
     * @return 包含 MD5 和 URL 主路径的数组，索引 0 为 MD5，索引 1 为 URL 主路径  索引2为文件浏览器预览路径
     * @throws IllegalArgumentException 如果响应体格式不正确或缺少关键字段
     */
    public static String[] parseFastDFSResponse(String responseBody) {
        if (JSONUtil.isJson(responseBody)) {
            JSONObject jsonObject = JSONUtil.parseObj(responseBody);
            // 提取 MD5 值
            String md5 = jsonObject.getStr("md5");
            if (md5 == null || md5.isEmpty()) {
                throw new IllegalArgumentException("响应中缺少 MD5 字段");
            }

            // 提取原始 URL 并处理
            String fullUrl = jsonObject.getStr("url");
            if (fullUrl == null || fullUrl.isEmpty()) {
                throw new IllegalArgumentException("响应中缺少 URL 字段");
            }

            // 截取 URL 到问号前的部分
            String urlWithoutQuery = getUrlWithoutQuery(fullUrl);

            // 预览图片的地址
            String domain = jsonObject.getStr("domain");
            if (domain == null || domain.isEmpty()) {
                throw new IllegalArgumentException("响应中缺少 domain 字段");
            }


            String src = jsonObject.getStr("src");
            if (src == null || src.isEmpty()) {
                throw new IllegalArgumentException("响应中缺少 src 字段");
            }

            String previewUrl = domain+src+"?download=0";

            return new String[]{md5, urlWithoutQuery, previewUrl};
        } else {
            throw new IllegalArgumentException("传入的不是有效的 JSON 字符串");
        }
    }


    /**
     * 从完整 URL 中提取主路径（去除查询参数和锚点）
     * @param fullUrl 完整 URL 字符串
     * @return 主路径部分（例如：http://example.com/path/to/file）
     */
    private static String getUrlWithoutQuery(String fullUrl) {
        int queryIndex = fullUrl.indexOf('?');
        return queryIndex != -1 ? fullUrl.substring(0, queryIndex) : fullUrl;
    }

}
